#include "interpreter.h"

Interpreter::Interpreter(string filename)
{
    this->m_filename = filename;
}
Interpreter::~Interpreter()
{

}
void Interpreter::parseFile()
{
    fstream file;
    file.open(this->m_filename,ios::in);
    if(!file.is_open()){
        cout << "open file " << this->m_filename << " error" << endl;
    }
    string line;
    while(getline(file,line)){
        // cout << line << endl;
        if(!isJumpOver(line)){
            this->parseLine(line);
        }
    }
    // cout << "word as follow" << endl;
    // this->printWord(this->v_word);
    file.close();
    // this->printTree(this->umapStep);
}

void Interpreter::parseLine(const string& line)
{
    // cout << line << endl;
    vector<string> token;
    token.clear();
    int len = line.length();
    string str;
    str.clear();
    for(int i=0; i<len; i++) {
        //注释退出
        if(line[i] == '#') break;
        //处理str 当前是分隔符 且str已经有记录
        if(this->isDelimiter(line[i]) && str.length() > 0){
            token.push_back(str);
            // cout << str << endl;
            str.clear();
        }
        if(!isDelimiter(line[i])){
            str += line[i];
        }
    }
    //最后一个str
    if(str.length() > 0){
        token.push_back(str);
        // cout << str << endl;
    }

    if(token.size() > 0){
        this->ProcessTokens(token);
    }
}

void Interpreter::ProcessTokens(const vector<string>& token)
{
    cout << token[0] << "    ";
    if(token[0] == "Step"){
        //创建新块
        cout << token[1] << endl;

        this->ProcessStep(token[1]);
    }else if(token[0] == "Speak"){
        cout << token[1] << endl;

        this->ProcessSpeak(token);
    }else if(token[0] == "Listen"){
        int startTimer = atoi((char*)token[1].data());
        int endTimer = atoi((char*)token[2].data());
        cout << startTimer << " " << endTimer << endl;

        this->ProcessListen(startTimer,endTimer);
    }else if(token[0] == "Branch"){
        string answer = token[1];
        string nextStepId = token[2];
        cout << answer << " " << nextStepId << endl;

        this->ProcessBranch(answer,nextStepId);
    }else if(token[0] == "Silence"){
        string nextStepId = token[1];
        cout << nextStepId << endl;

        this->ProcessSilence(nextStepId);
    }else if(token[0] == "Default"){
        string nextStepId = token[1];
        cout << nextStepId << endl;

        this->ProcessDefault(nextStepId);
    }else if(token[0] == "Exit"){
        cout << endl;
        this->ProcessExit();
    }else{
        cout << "脚本错误" << endl;
        exit(-1);
    }
}

void Interpreter::ProcessStep(const string& expression)
{
    // cout << "create................" << endl;
    //新step创建完成 这里会遗漏最后一个step
    if(this->curStep.is_create){
        this->umapStep.insert(pair<string,TreeNode>(curStep.Expression,curStep));
        //用于刷新curStep
        TreeNode tem;
        this->curStep = tem;
        // cout << "xxxx create success xxxx" << endl;
    }

    //创建一个新的Step 标识为stepId
    curStep.Expression = expression;
    curStep.is_create = true;

    //第一个step作为mainstep
    if(this->umapStep.size() == 0){
        this->mainStep = expression;
    }
}

void Interpreter::ProcessSpeak(const vector<string>& token)
{
    this->curStep.is_speak = true;
    for(auto it = token.begin()+1; it != token.end(); it++){
        //将第二个到最后一个放入curStep
        this->ProcessExpression(*it);
    }
}

void Interpreter::ProcessExpression(const string& s)
{
    curStep.item.push_back(s);
    //warn:这里还没考虑变量命名
}

void Interpreter::ProcessListen(int startTimer,int stopTimer)
{
    this->curStep.is_listen = true;
    curStep.beginTimer = startTimer;
    curStep.endTimer = stopTimer;
}

void Interpreter::ProcessBranch(const string& answer, const string& nextStepId)
{
    this->curStep.is_branch = true;
    this->curStep.HashTable.insert(pair<string,string>(answer,nextStepId));
}

void Interpreter::ProcessSilence(const string& nextStepId)
{
    this->curStep.is_silence = true;
    this->curStep.silence = nextStepId;
}

void Interpreter::ProcessDefault(const string& nextStepId)
{
    this->curStep.is_defaultProc = true;
    this->curStep.defaultProc = nextStepId;
}

void Interpreter::ProcessExit()
{
    //设置为终结step
    this->curStep.is_Exit = true;
}

void Interpreter::InterpreterRunner(bool isTest)
{
    //记录主模块
    TreeNode cstep = this->getNodeByName(this->mainStep);
    //轮换cstep执行脚本 直到某次step有退出标志
    bool cycle = true;
    while(cycle){
        //退出标志校验
        if(cstep.is_Exit){
            cycle = false;
        }
        //改变分支标志
        bool notChangeStep = true;
        if(cstep.is_speak){
            if(isTest){
                cstep.speakInfo(this->_name,this->_amount,true,this->outFilePath);
            }else{
                cstep.speakInfo(this->_name,this->_amount);
            }
        }
        if(cstep.is_listen){
            int waitTimer = cstep.endTimer - cstep.beginTimer;
            string user_input;
            bool is_input;
            if(isTest){
                //测试板块
                if(this->sleep_times > 0){
                    //休眠一次
                    this->sleep_times--;
                    //比对休眠时间 和 waitTimer
                    if(this->sleep_length < waitTimer){
                        //回馈
                        is_input = true;
                        user_input = this->v_user_input[this->input_ptr++];
                        cout << "模拟输入:" << user_input << endl;
                    }else{
                        //超时 不回馈
                        is_input = false;
                        cout << "模拟输入超时" << endl;
                    }
                }else{
                    is_input = true;
                    user_input = this->v_user_input[this->input_ptr++];
                    cout << "模拟输入:" << user_input << endl;
                }
            }else{
                //正常程序
                is_input = this->get_input(user_input,waitTimer);
            }
            //超时状况 待完成
            if(!is_input && notChangeStep && cstep.is_silence){
                // cout << cstep.silence << endl;
                cstep = this->getNodeByName(cstep.silence);
                notChangeStep = false;
            }
            //有分支才进行处理
            if(notChangeStep && cstep.is_branch){
                //遍历分支 对比
                for(auto it = cstep.HashTable.begin(); it != cstep.HashTable.end() && notChangeStep; it++){
                    //比对分支条件 和 用户查询
                    if(this->isMatch(it->first,user_input)){
                        //跳转分支
                        cstep = this->getNodeByName(it->second);
                        //分支改变
                        notChangeStep = false;
                    }
                }
            }
            //默认分支
            if(notChangeStep && cstep.is_defaultProc){
                // cout << cstep.defaultProc << endl;
                cstep = this->getNodeByName(cstep.defaultProc);
                notChangeStep = false;
            }
        }
    }
}

bool Interpreter::isJumpOver(const string& line)
{
    //空 跳过
    if(line.length() == 0){
        return true;
    }
    //注释 跳过
    if(line[0] == '#'){
        return true;
    }
    //换行 跳过
    if(line[0] == 13){
        return true;
    }
    //空格 跳过
    bool ret = true;
    for(int i=0; i<line.length(); i++){
        if(line[i] != ' '){
            ret = false;
        }
    }
    return ret;
}

bool Interpreter::isDelimiter(char c)
{
    //13是回车键
    return c == ' ' || c == ';' || c == ',' || c == '+' || c == 13 || c == '"';
}

void Interpreter::printWord(vector<string>& s)
{
    for(auto it = s.begin(); it != s.end(); it++){
        cout << (*it) << endl;
        // cout << (*it).length() << ":" << (*it) << endl;
        // if((*it).length() == 1){
        //     printf("<%d>\n",(*it)[0]);
        // }
    }
}

void Interpreter::printTree(unordered_map<string,TreeNode>& umap)
{
    for(auto uit = umap.begin(); uit != umap.end(); uit++){
        // cout << "name:" << uit->first << endl;
        uit->second.showData();
    }
}

TreeNode Interpreter::getNodeByName(const string& name)
{
    auto fstep = this->umapStep.find(name);
    if(fstep == this->umapStep.end()){
        cout << "error" << endl;
        exit(-1);
    }
    return fstep->second;
}

bool Interpreter::isMatch(const string& branchWord,const string& querySentence)
{
    string::size_type idx;
    idx = querySentence.find(branchWord);
    //不存在
    if(idx == string::npos){
        return false;
    }else{
        return true;
    }

}

bool Interpreter::get_input(string& ret,int wTimer)
{
    //struct fd_set可以理解为一个集合，这个集合中存放的是文件描述符(filedescriptor)，即文件句柄
    fd_set rfds;
    struct timeval tv;
    int ch = 0;
    //清空集合
    FD_ZERO(&rfds);
    //将一个给定的文件描述符加入集合之中
    FD_SET(0, &rfds);
    //超时标志 s ms
    // tv.tv_sec = 5;
    tv.tv_sec = wTimer;
    tv.tv_usec = 0; 
    //检测键盘是否有输入
    if (select(1, &rfds, NULL, NULL, &tv) > 0)
    {
        cin >> ret;
    }
    
    if(ret == ""){
        // cout << "no input" << endl;
        return false;
    }else{
        // cout << ret << endl;
        return true;
    }
}

void Interpreter::getUserInfo(int id)
{
    fstream ufile;
    ufile.open(USER_INFO_FILE,ios::in);
    if(!ufile.is_open()){
        cout << "open file " << USER_INFO_FILE << " error" << endl;
        exit(-1);
    }
    int uid;
    string uname;
    int uamount;
    while(ufile >> uid >> uname >> uamount){
        if(uid == id){
            this->_name = uname;
            this->_amount = uamount;
            break;
        }
    }
}
